package com.example.provider.service;

import com.example.api.UserService;
import com.example.api.common.BusinessException;
import com.example.api.common.annotation.LogTag;
import com.example.api.common.message.KafkaMessage;
import com.example.api.entity.User;
import com.example.provider.entity.UserEntity;
import com.example.provider.mapper.UserMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@DubboService
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    
    private static final String USER_CACHE_KEY_PREFIX = "user:";
    private static final String USER_REGISTER_TOPIC = "user-register";
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    @LogTag("sayHello")
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
    
    @Override
    @Transactional
    @LogTag("register")
    public User register(User apiUser) {
        // 参数校验
        if (apiUser.getUsername() == null || apiUser.getUsername().trim().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }
        if (apiUser.getPassword() == null || apiUser.getPassword().trim().isEmpty()) {
            throw new BusinessException("密码不能为空");
        }
        
        // 检查用户名是否已存在
        UserEntity existingUser = userMapper.selectOne(
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserEntity>()
                .eq(UserEntity::getUsername, apiUser.getUsername())
        );
        if (existingUser != null) {
            throw new BusinessException("用户名已存在");
        }
        
        // 1. 保存到MySQL
        UserEntity user = new UserEntity();
        BeanUtils.copyProperties(apiUser, user);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
        
        // 2. 发送注册事件到Kafka
        try {
            KafkaMessage<String> message = KafkaMessage.of(user.getUsername());
            kafkaTemplate.send(USER_REGISTER_TOPIC, objectMapper.writeValueAsString(message));
        } catch (Exception e) {
            throw new BusinessException("发送注册事件失败");
        }
        
        // 3. 缓存用户信息到Redis
        String cacheKey = USER_CACHE_KEY_PREFIX + user.getUsername();
        redisTemplate.opsForValue().set(cacheKey, user, 1, TimeUnit.HOURS);
        
        // 4. 返回结果
        BeanUtils.copyProperties(user, apiUser);
        return apiUser;
    }
    
    @Override
    @LogTag("findByUsername")
    public User findByUsername(String username) {
        if (username == null || username.trim().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }
        
        // 1. 先从Redis缓存中查询
        String cacheKey = USER_CACHE_KEY_PREFIX + username;
        UserEntity cachedUser = (UserEntity) redisTemplate.opsForValue().get(cacheKey);
        
        if (cachedUser != null) {
            User apiUser = new User();
            BeanUtils.copyProperties(cachedUser, apiUser);
            return apiUser;
        }
        
        // 2. 缓存未命中，从MySQL查询
        UserEntity user = userMapper.selectOne(
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserEntity>()
                .eq(UserEntity::getUsername, username)
        );
        
        if (user != null) {
            // 3. 将查询结果缓存到Redis
            redisTemplate.opsForValue().set(cacheKey, user, 1, TimeUnit.HOURS);
            
            // 4. 返回结果
            User apiUser = new User();
            BeanUtils.copyProperties(user, apiUser);
            return apiUser;
        }
        
        throw new BusinessException("用户不存在");
    }
    
    @Override
    @Transactional
    @LogTag("updateUser")
    public User updateUser(User apiUser) {
        if (apiUser.getUsername() == null || apiUser.getUsername().trim().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }
        
        // 检查用户是否存在
        UserEntity existingUser = userMapper.selectOne(
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<UserEntity>()
                .eq(UserEntity::getUsername, apiUser.getUsername())
        );
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 1. 更新MySQL
        UserEntity user = new UserEntity();
        BeanUtils.copyProperties(apiUser, user);
        user.setId(existingUser.getId());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);
        
        // 2. 更新Redis缓存
        String cacheKey = USER_CACHE_KEY_PREFIX + user.getUsername();
        redisTemplate.opsForValue().set(cacheKey, user, 1, TimeUnit.HOURS);
        
        // 3. 返回结果
        BeanUtils.copyProperties(user, apiUser);
        return apiUser;
    }
} 